/*
 * $Id$
 *
 * Copyright ( c ) 2014 XuNuo Corporation. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of XuNuo
 * Corporation ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with XuNuo Corporation or a XuNuo
 * authorized reseller (the "License Agreement"). XuNuo may make changes to the
 * Confidential Information from time to time. Such Confidential Information may
 * contain errors.
 *
 * EXCEPT AS EXPLICITLY SET FORTH IN THE LICENSE AGREEMENT, XuNuo DISCLAIMS ALL
 * WARRANTIES, COVENANTS, REPRESENTATIONS, INDEMNITIES, AND GUARANTEES WITH
 * RESPECT TO SOFTWARE AND DOCUMENTATION, WHETHER EXPRESS OR IMPLIED, WRITTEN OR
 * ORAL, STATUTORY OR OTHERWISE INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A
 * PARTICULAR PURPOSE. XuNuo DOES NOT WARRANT THAT END USER'S USE OF THE
 * SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR SECURE.
 *
 * XuNuo SHALL NOT BE LIABLE TO END USER, OR ANY OTHER PERSON, CORPORATION OR
 * ENTITY FOR INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL
 * DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR USE, WHETHER IN AN
 * ACTION IN CONTRACT, TORT OR OTHERWISE, EVEN IF XuNuo HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES. XuNuo' TOTAL LIABILITY TO END USER SHALL NOT
 * EXCEED THE AMOUNTS PAID FOR THE XuNuo SOFTWARE BY END USER DURING THE PRIOR
 * TWELVE (12) MONTHS FROM THE DATE IN WHICH THE CLAIM AROSE.  BECAUSE SOME
 * STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL
 * OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO END USER.
 *
 * Copyright version 2.0
 */
package com.th.supcom.pds.internal.client.widget;

import net.carefx.fc.component.editor.client.EMREditorPanel;
import net.carefx.fc.component.editor.client.command.Command.CommandBuilder;
import net.carefx.fc.component.editor.client.data.ArgModel;
import net.carefx.fc.component.editor.client.data.InitListener;
import net.carefx.fc.component.editor.client.utils.ActivexUtils;

import com.extjs.gxt.ui.client.Style.HideMode;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.th.supcom.pds.common.client.model.CodeConstants;
import com.th.supcom.pds.common.enums.ComponentType;
import com.th.supcom.pds.common.enums.MedicareCardTypeEnum;
import com.th.supcom.pds.common.enums.TJToolCommand;
import com.th.supcom.pds.internal.client.common.PdsInternalServiceFactory;
import com.th.supcom.pds.internal.client.model.PatientInfoModel;
import com.th.supcom.pds.internal.client.service.MedicareCardRpcAsync;

/**
 * 刷卡输入框
 * 
 * @author 杨冲
 */
public abstract class MedicareCardField extends BaseCardField
{
    /** 公司版权信息. */
    public static final String copyright = "Copyright 2014, XuNuo Corporation";
    private static final MedicareCardRpcAsync s_MEDICARECARDRPCASYNC = PdsInternalServiceFactory.getMedicareCardService ();

    /** 提交路径. */
    public static final String SCC_BRANCH = "$URL$";

    /** 提交日期. */
    public static final String SCC_LAST_MODIFICATION_DATE = "$Date$";

    /** 最终修改人员. */
    public static final String SCC_LAST_MODIFIER_NAME = "$Author$";

    /** 最终版本号. */
    public static final String SCC_REVISION = "$Revision$";

    private final EMREditorPanel m_noipEditorPanel;

    /**
     * 构造函数
     * 
     * @param panel
     */
    public MedicareCardField (final ContentPanel panel)
    {
        m_medicareCardAllInfoModel = new PatientInfoModel ();

        // 初始化TextField
        setPassword (true);
        // setEnabled (false);
        // 通过EMREditor组件来调用TJTool命令
        m_noipEditorPanel = new EMREditorPanel ("pts_swipe_card" + ActivexUtils.getEMREditorIndex (),
                                                ComponentType.TJTool);
        m_noipEditorPanel.setHideMode (HideMode.OFFSETS);
        m_noipEditorPanel.setVisible (true);

        m_noipEditorPanel.setListener (new InitListener ()
        {
            @Override
            public void afterInit ()
            {
                addCardListener ();
            }
        });
        panel.add (m_noipEditorPanel);
    }

    /**
     * 添加医疗卡刷卡触发事件
     */
    public void addCardListener ()
    {
        addListener (Events.Change, new Listener <BaseEvent> ()
        {
            @Override
            public void handleEvent (final BaseEvent be)
            {
                if (null == getValue ())
                {
                    return;
                }

                final ArgModel <Object> argModel = new ArgModel <Object> ();
                argModel.set ("CardOrgInfo", getValue ());
                final String arg = m_noipEditorPanel.syncExecute (new CommandBuilder (TJToolCommand.DISTINGUISH_CARD).buildArgModel (argModel)
                                                                                                                     .create ());
                JSONValue jSONValue = JSONParser.parseLenient (arg);
                JSONObject object = jSONValue.isObject ();
                final String args = object.get ("args").isString ().stringValue ();
                jSONValue = JSONParser.parseLenient (args);
                object = jSONValue.isObject ();

                final BaseMedicareCard medicareCard = parseCard (object);

                if (null == medicareCard)
                {
                    MessageBox.alert (CodeConstants.PROMPT, "此就诊卡无效，请重刷!", null);
                    return;

                }
                MedicareCardField.s_MEDICARECARDRPCASYNC.getMedicareAllCard (medicareCard.getSecondTrackInfo (),
                                                                             MedicareCardTypeEnum.AttendanceCard.getEnumCode (),
                                                                             "0",
                                                                             new AsyncCallback <PatientInfoModel> ()
                                                                             {

                                                                                 @Override
                                                                                 public void onFailure (final Throwable caught)
                                                                                 {
                                                                                     MessageBox.alert (CodeConstants.PROMPT,
                                                                                                       caught.getMessage (),
                                                                                                       null);
                                                                                 }

                                                                                 @Override
                                                                                 public void onSuccess (final PatientInfoModel result)
                                                                                 {
                                                                                     m_medicareCardAllInfoModel = result;
                                                                                     handleEventAfter ();
                                                                                 }
                                                                             });
            }
        });
    }

    /**
     * @param cardType
     * @param firstTrackInfo
     * @param secondTrackInfo
     * @param thirdTrackInfo
     */
    private BaseMedicareCard createCard (final String cardType, final String firstTrackInfo,
                                         final String secondTrackInfo, final String thirdTrackInfo)
    {
        if (MedicareCardTypeEnum.Invalid.getEnumCode ().equals (cardType))
        {
            return null;
        }

        if (MedicareCardTypeEnum.AttendanceCard.getEnumCode ().equals (cardType))
        {
            return new AttendanceCard (cardType, firstTrackInfo, secondTrackInfo, thirdTrackInfo);
        }

        if (MedicareCardTypeEnum.HealthCard.getEnumCode ().equals (cardType))
        {
            return new HealthCard (cardType, firstTrackInfo, secondTrackInfo, thirdTrackInfo);
        }
        return null;
    }

    /**
     * 获取医疗卡患者信息及卡信息
     * 
     * @return
     */
    @Override
    public PatientInfoModel getModelValue ()
    {
        return m_medicareCardAllInfoModel;
    }

    /**
     * 解析得到卡
     * 
     * @param object
     * @return BaseMedicareCard
     */
    private BaseMedicareCard parseCard (final JSONObject object)
    {
        final String cardType = object.get ("CardType").isString ().stringValue ();
        final String firstTrackInfo = null == object.get ("FirstTrackInfo") ? null : object.get ("FirstTrackInfo")
                                                                                           .isString ().stringValue ();
        final String secondTrackInfo = null == object.get ("SecondTrackInfo") ? null : object.get ("SecondTrackInfo")
                                                                                             .isString ()
                                                                                             .stringValue ();
        final String thirdTrackInfo = null == object.get ("ThirdTrackInfo") ? null : object.get ("ThirdTrackInfo")
                                                                                           .isString ().stringValue ();

        return createCard (cardType, firstTrackInfo, secondTrackInfo, thirdTrackInfo);
    }
}
